<?php
namespace App\Http\Controllers\API;

use App\Http\Controllers\API\BaseController as BaseController;
use App\User;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Validator;

class LoginController extends BaseController {
	/**
	 * Register api
	 *
	 * @return \Illuminate\Http\Response
	 */
	public function register(Request $request) {
		$validator = Validator::make($request->all(), [
			'name' => 'required',
			'email' => 'required|email|unique:users',
			'password' => 'required',
			'c_password' => 'required|same:password',
		]);
		if ($validator->fails()) {
			return $this->sendError('Validation Error.', 422, $validator->errors());
		}
		$input = $request->all();
		$input['password'] = bcrypt($input['password']);
		try {
			$user = User::create($input);
			$success['token'] = $user->createToken('Personal')->accessToken;
			$success['name'] = $user->name;
			return $this->sendResponse($success, 'User register successfully.');
		} catch (Exception $e) {
			return $this->sendError($e->getmessage(), 300);
		}
	}

	public function login(Request $request) {

		$credentials = [
			'name' => $request->username,
			'password' => $request->password,
		];
		//dump($request->all());
		return $this->sendResponse($credentials, 'test.');
		if (auth()->attempt($credentials)) {
			/* remove old tokens */
			$tokens = auth()->user()->tokens;
			foreach ($tokens as $tKey => $token) {
				$token->delete();
			}
			/* end create old token */
			$success['token'] = $tokens;
			$success['user'] = $auth()->user;
			return $this->sendResponse($success, 'User Login successfully.');
		} else {
			$msg = 'User Name Password Does Not Match';
			return $this->sendError($msg, 401);
		}
	}

	/**
	 * Returns Authenticated User Details
	 *
	 * @return \Illuminate\Http\JsonResponse
	 */
	public function details() {
		return response()->json([auth()->user()->createToken('Personal')->accessToken],200);
		return response()->json(['user' => auth()->user()], 200);
	}
	/**
	 * invalid token token
	 *
	 * @return json
	 * @author
	 **/
	public function invalidToken(Request $request) {
		$msg = 'Token is Not Valid Or Expired';
		return $this->sendError($msg, 401);
	}
}

/*

个人访问令牌
有时，您的用户可能希望在不经过典型授权代码重定向流的情况下向自己发出访问令牌。允许用户通过应用程序的UI向自己发放令牌对于允许用户试验您的API非常有用，或者可以作为一般发布访问令牌的简单方法。


创建个人访问客户端
在您的应用程序发出个人访问令牌之前，您需要创建一个个人访问客户端。您可以使用带有该选项的命令执行此操作。如果您已经运行该命令，则无需运行此命令：passport:client--personalpassport:install

php artisan passport:client --personal
如果您已经定义了个人访问客户端，则可以指示Passport使用该personalAccessClientId方法使用它。通常，应该从以下boot方法调用此方法AuthServiceProvider：


public function boot()
{
    $this->registerPolicies();

    Passport::routes();

    Passport::personalAccessClientId('client-id');
}

管理个人访问令牌
创建个人访问客户端后，您可以使用模型实例createToken上的方法为给定用户发出令牌User。该createToken方法接受令牌的名称作为其第一个参数，并将可选的作用域数组作为其第二个参数：

$user = App\User::find(1);

// Creating a token without scopes...
$token = $user->createToken('Token Name')->accessToken;

// Creating a token with scopes...
$token = $user->createToken('My Token', ['place-orders'])->accessToken;
JSON API
Passport还包括用于管理个人访问令牌的JSON API。您可以将其与您自己的前端配对，为您的用户提供用于管理个人访问令牌的仪表板。下面，我们将审核用于管理个人访问令牌的所有API端点。为方便起见，我们将使用Axios演示向端点发出HTTP请求。

该JSON API由看守web和auth中间件; 因此，它只能从您自己的应用程序中调用。它无法从外部源调用。

如果您不想自己实现个人访问令牌前端，可以使用前端快速入门在几分钟内拥有一个功能齐全的前端。

GET /oauth/scopes
此路由返回为应用程序定义的所有范围。您可以使用此路由列出用户可以分配给个人访问令牌的范围：

axios.get('/oauth/scopes')
    .then(response => {
        console.log(response.data);
    });
GET /oauth/personal-access-tokens
此路由返回经过身份验证的用户创建的所有个人访问令牌。这主要用于列出所有用户的令牌，以便他们可以编辑或删除它们：

axios.get('/oauth/personal-access-tokens')
    .then(response => {
        console.log(response.data);
    });
POST /oauth/personal-access-tokens
此路线创建新的个人访问令牌。它需要两个数据：令牌name和scopes应该分配给令牌：

const data = {
    name: 'Token Name',
    scopes: []
};

axios.post('/oauth/personal-access-tokens', data)
    .then(response => {
        console.log(response.data.accessToken);
    })
    .catch (response => {
        // List errors on response...
    });
DELETE /oauth/personal-access-tokens/{token-id}
此路线可用于删除个人访问令牌：

axios.delete('/oauth/personal-access-tokens/' + tokenId);

保护路线

通过中间件
Passport包含一个身份验证防护，可以验证传入请求的访问令牌。配置api防护使用passport驱动程序后，只需在需要有效访问令牌的任何路由上指定中间件：auth:api

Route::get('/user', function () {
    //
})->middleware('auth:api');

传递访问令牌
在调用受Passport保护的路由时，应用程序的API使用者应将其访问令牌指定为其请求标头中的Bearer标记Authorization。例如，使用Guzzle HTTP库时：

$response = $client->request('GET', '/api/user', [
    'headers' => [
        'Accept' => 'application/json',
        'Authorization' => 'Bearer '.$accessToken,
    ],
]);

检查范围
Passport包括两个中间件，可用于验证传入请求是否已使用已授予给定范围的令牌进行身份验证。首先，将以下中间件添加到文件的$routeMiddleware属性中：app/Http/Kernel.php

'scopes' => \Laravel\Passport\Http\Middleware\CheckScopes::class,
'scope' => \Laravel\Passport\Http\Middleware\CheckForAnyScope::class,
检查所有范围
该scopes中间件可以被分配到的路线，以验证传入的请求的访问令牌的所有列出的作用域：

Route::get('/orders', function () {
    // Access token has both "check-status" and "place-orders" scopes...
})->middleware('scopes:check-status,place-orders');
检查任何范围
该scope中间件可以被分配给一个路由来验证传入的请求的访问令牌具有至少一个所列出的范围的：

Route::get('/orders', function () {
    // Access token has either "check-status" or "place-orders" scope...
})->middleware('scope:check-status,place-orders');
检查令牌实例上的范围
一旦访问令牌经过身份验证的请求进入了您的应用程序，您仍然可以使用tokenCan经过身份验证的User实例上的方法检查令牌是否具有给定范围：

use Illuminate\Http\Request;

Route::get('/orders', function (Request $request) {
    if ($request->user()->tokenCan('place-orders')) {
        //
    }
});
附加范围方法
该scopeIds方法将返回所有已定义ID /名称的数组：

Laravel\Passport\Passport::scopeIds();
该scopes方法将返回所有已定义范围的数组作为以下实例：Laravel\Passport\Scope

Laravel\Passport\Passport::scopes();
该scopesFor方法将返回与给定ID /名称匹配的实例数组：Laravel\Passport\Scope

Laravel\Passport\Passport::scopesFor(['place-orders', 'check-status']);
您可以使用以下hasScope方法确定是否已定义给定范围：

Laravel\Passport\Passport::hasScope('place-orders');

使用JavaScript消耗您的API
构建API时，能够从JavaScript应用程序中使用自己的API非常有用。这种API开发方法允许您自己的应用程序使用与您共享的相同API。您的Web应用程序，移动应用程序，第三方应用程序以及您可能在各种程序包管理器上发布的任何SDK都可能使用相同的API。

通常，如果要从JavaScript应用程序中使用API​​，则需要手动将访问令牌发送到应用程序，并将每个请求传递给应用程序。但是，Passport包含一个可以为您处理此问题的中间件。您需要做的就是将CreateFreshApiToken中间件添加到文件中的web中间件组：app/Http/Kernel.php

'web' => [
    // Other middleware...
    \Laravel\Passport\Http\Middleware\CreateFreshApiToken::class,
],
您应确保在中间件堆栈中的中间件EncryptCookies之前列出CreateFreshApiToken中间件。

这个Passport中间件会将laravel_tokencookie 附加到您的外发响应中。此cookie包含一个加密的JWT，Passport将使用该JWT来验证来自JavaScript应用程序的API请求。现在，您可以在不显式传递访问令牌的情况下向应用程序的API发出请求：

axios.get('/api/user')
    .then(response => {
        console.log(response.data);
    });
自定义Cookie名称
如果需要，您可以laravel_token使用该方法自定义cookie的名称。通常，应该从以下方法调用此方法：Passport::cookiebootAuthServiceProvider


public function boot()
{
    $this->registerPolicies();

    Passport::routes();

    Passport::cookie('custom_name');
}
CSRF保护
使用此身份验证方法时，您需要确保请求中包含有效的CSRF令牌标头。默认的Laravel JavaScript脚手架包括一个Axios实例，该实例将自动使用加密的cookie值在同源请求上发送标头。XSRF-TOKENX-XSRF-TOKEN

如果您选择发送标头而不是，则需要使用提供的未加密令牌。X-CSRF-TOKENX-XSRF-TOKENcsrf_token()


活动
Passport在发出访问令牌和刷新令牌时引发事件。您可以使用这些事件来修剪或撤消数据库中的其他访问令牌。您可以在应用程序中将侦听器附加到这些事件EventServiceProvider：


protected $listen = [
    'Laravel\Passport\Events\AccessTokenCreated' => [
        'App\Listeners\RevokeOldTokens',
    ],

    'Laravel\Passport\Events\RefreshTokenCreated' => [
        'App\Listeners\PruneOldTokens',
    ],
];

测试
Passport的actingAs方法可用于指定当前已验证的用户及其范围。给该actingAs方法的第一个参数是用户实例，第二个参数是应该授予用户令牌的范围数组：

use App\User;
use Laravel\Passport\Passport;

public function testServerCreation()
{
    Passport::actingAs(
        factory(User::class)->create(),
        ['create-servers']
    );

    $response = $this->post('/api/create-server');

    $response->assertStatus(201);
}
*/